package yunjiao.javatutorials.guava.concurrent;

import com.google.common.util.concurrent.AbstractExecutionThreadService;

import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 监控服务示例
 *
 * @author yangyunjiao
 */
public class MonitoringService  extends AbstractExecutionThreadService {

    private final AtomicInteger errorCount = new AtomicInteger(0);
    private final long checkIntervalMs;

    public MonitoringService(long checkIntervalMs) {
        this.checkIntervalMs = checkIntervalMs;
    }

    @Override
    protected void startUp() throws Exception {
        System.out.println("监控服务初始化完成");
        System.out.println("检查间隔: " + checkIntervalMs + "ms");
    }

    @Override
    protected void run() throws Exception {
        while (isRunning()) {
            try {
                if (new Random().nextBoolean()) {
                    throw new RuntimeException("检查异常");
                }
                // 执行监控检查
                performHealthCheck();

                // 模拟一些系统检查
                checkSystemResources();

                // 定期休眠
                Thread.sleep(checkIntervalMs);

            } catch (InterruptedException e) {
                // 如果服务正在停止，则退出循环
                if (!isRunning()) {
                    break;
                }
            } catch (Exception e) {
                errorCount.incrementAndGet();
                System.err.println("监控检查出错: " + e.getMessage());
            }
        }
    }

    @Override
    protected void triggerShutdown() {
        System.out.println("监控服务停止信号已接收");
    }

    @Override
    protected void shutDown() throws Exception {
        System.out.println("监控服务关闭，总错误数: " + errorCount.get());
    }

    private void performHealthCheck() {
        System.out.println("[" + LocalDateTime.now() + "] 执行健康检查 - 错误计数: " + errorCount.get());
        // 实际的健康检查逻辑
    }

    private void checkSystemResources() {
        // 模拟系统资源检查
        Runtime runtime = Runtime.getRuntime();
        long freeMemory = runtime.freeMemory();
        long totalMemory = runtime.totalMemory();
        double memoryUsage = (double) (totalMemory - freeMemory) / totalMemory * 100;

        System.out.printf("内存使用率: %.2f%%\n", memoryUsage);
    }

    public int getErrorCount() {
        return errorCount.get();
    }

    public static void main(String[] args) throws InterruptedException, TimeoutException {
        MonitoringService service = new MonitoringService(600);

        // 1. 启动服务（异步）
        service.startAsync();
        service.awaitRunning(); // 阻塞等待服务启动完成
        System.out.printf("[主线程] 服务已启动（状态：%s）%n", service.state());

        // 2. 运行3秒后停止服务
        TimeUnit.SECONDS.sleep(3);
        service.stopAsync(); // 异步停止
        System.out.printf("[主线程] 已触发服务停止（状态：%s）%n", service.state());

        // 3. 等待服务终止（最多等待2秒）
        service.awaitTerminated(2, TimeUnit.SECONDS);
        System.out.printf("[主线程] 服务正常终止（状态：%s）%n", service.state());

    }
}
